package com.mall.user.utils;

import org.mindrot.jbcrypt.BCrypt;

/**
 * 密码加密与验证工具类
 * 使用 BCrypt 算法对密码进行哈希处理和验证。
 * BCrypt 算法安全、内置盐值，是存储用户密码的推荐方式。
 */
public class PasswordUtil {

    // 定义 BCrypt 的工作因子 (work factor)
    // 这个值控制哈希计算的强度（成本）。值越高，计算越慢，安全性越高，但也更消耗 CPU。
    // 通常在 4-31 之间。10-12 是常见且平衡的选择。
    // 可以根据服务器性能和安全需求调整。
    private static final int BCRYPT_WORK_FACTOR = 12;

    /**
     * 对明文密码进行加密（哈希）
     *
     * @param plainPassword 明文密码
     * @return 加密后的哈希字符串（包含盐值和哈希值）
     * @throws IllegalArgumentException 如果输入的密码为 null
     */
    public static String hashPassword(String plainPassword) {
        if (plainPassword == null) {
            throw new IllegalArgumentException("明文密码不能为 null");
        }
        // 使用指定的工作因子生成哈希
        return BCrypt.hashpw(plainPassword, BCrypt.gensalt(BCRYPT_WORK_FACTOR));
    }

    /**
     * 验证明文密码与数据库中存储的哈希密码是否匹配
     *
     * @param plainPassword 明文密码（用户登录时输入）
     * @param hashedPassword 数据库中存储的哈希密码
     * @return 如果密码匹配返回 true，否则返回 false
     * @throws IllegalArgumentException 如果任一参数为 null
     */
    public static boolean verifyPassword(String plainPassword, String hashedPassword) {
        if (plainPassword == null || hashedPassword == null) {
            throw new IllegalArgumentException("明文密码和哈希密码均不能为 null");
        }
        return BCrypt.checkpw(plainPassword, hashedPassword);
    }

    /**
     * （可选）检查数据库中的哈希密码是否使用了当前配置的工作因子。
     * 如果不是，可以在用户下次成功登录时更新其哈希值（使用新的工作因子）。
     * 这有助于逐步升级旧密码的强度。
     *
     * @param hashedPassword 数据库中存储的哈希密码
     * @return 如果哈希值使用了当前配置的工作因子则返回 true
     */
    public static boolean isPasswordHashUpToDate(String hashedPassword) {
        if (hashedPassword == null) {
            return false;
        }
        try {
            // BCrypt 哈希格式为 $2a$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
            // 其中 10 是成本因子（以 2 为底的对数）
            // 提取成本因子部分
            String[] parts = hashedPassword.split("\\$");
            if (parts.length != 4) {
                return false; // 格式不正确
            }
            int storedCost = Integer.parseInt(parts[2]);
            return storedCost == BCRYPT_WORK_FACTOR;
        } catch (Exception e) {
            // 解析错误，认为不是最新的
            return false;
        }
    }

    // --- 使用示例 ---
    public static void main(String[] args) {
//        System.out.println(PasswordUtil.hashPassword("125344"));
        System.out.println(PasswordUtil.verifyPassword("125344", "$2a$12$LD46/eZaTaAMtamRcGWi7uuTqUBwgXhTshy76tnIamSeqCvmXNQ4e"));
//        String plainPassword = "MySecurePassword123!";
//
//        // 1. 注册或修改密码时：加密密码
//        String hashedPassword = hashPassword(plainPassword);
//        System.out.println("原始密码: " + plainPassword);
//        System.out.println("哈希后的密码: " + hashedPassword);
//
//        // 2. 将 hashedPassword 存储到数据库中（例如 user 表的 password_hash 字段）
//
//        // 3. 用户登录时：验证密码
//        String inputPassword = "MySecurePassword123!"; // 用户输入
//        boolean isMatch = verifyPassword(inputPassword, hashedPassword);
//        System.out.println("密码验证结果: " + isMatch); // 应该输出 true
//
//        // 测试错误密码
//        inputPassword = "WrongPassword";
//        isMatch = verifyPassword(inputPassword, hashedPassword);
//        System.out.println("密码验证结果 (错误密码): " + isMatch); // 应该输出 false
//
//        // 检查哈希是否使用了当前工作因子
//        System.out.println("哈希是否使用当前工作因子: " + isPasswordHashUpToDate(hashedPassword));
    }
}